package main

import (
	"bufio"
	"fmt"
	"io"
	"io/ioutil"
	"os"
)

// os.OpenFile的第二个参数`os.O_APPEND|os.O_CREATE|os.O_APPEND`-常量是二进制的计算
// 或运算：有1就为1
func writeToFile() {
	fileObj, err := os.OpenFile("./write.txt", os.O_APPEND|os.O_CREATE|os.O_APPEND, 0644)
	defer fileObj.Close()
	if err != nil {
		fmt.Printf("write from file failed, err: %v", err)
		return
	}
	fileObj.Write([]byte("字符串以切片类型写入\n"))
	fileObj.WriteString("直接写入字符串类型\n")
}

// 通过bufio写入

func writeToFileBufio() {
	/**
	* @Params {}string 路径
	* @Params {}常量 操作类型(追加或者创建)
	* @Params {}int 是文件权限(多用于Linux)
	 */
	fileObj, err := os.OpenFile("./write.txt", os.O_APPEND|os.O_CREATE, 0644)
	defer fileObj.Close()
	if err != nil {
		fmt.Printf("write from file failed, err: %v", err)
		return
	}
	// 创建一个写的对象
	wr := bufio.NewWriter(fileObj)
	// 此操作仅写入缓存中
	wr.Write([]byte("字符串以切片类型写入 bufio \n"))
	wr.WriteString("直接写入字符串类型 bufio \n")
	// 将缓存内的内容真正写入文件
	wr.Flush()
}

// 通过ioutil写入-覆盖了原文件内容
func writeToFileIoutil() {
	// ret, err := ioutil.ReadFile("./main.go")
	// if err != nil {
	// 	fmt.Printf("read from file of bufio failed, err: %v", err)
	// 	return
	// }
	ret := "直接写入字符串类型 ioutil \n"
	err := ioutil.WriteFile("./write.txt", []byte(string(ret)), 0666)
	if err != nil {
		fmt.Printf("write from file of bufio failed, err: %v", err)
		return
	}
}

// CopyFile 拷贝文件函数
func CopyFile(dstName, srcName string) (written int64, err error) {
	// 以读方式打开源文件
	src, err := os.Open(srcName)
	if err != nil {
		fmt.Printf("open %s failed, err:%v.\n", srcName, err)
		return
	}
	defer src.Close()
	// 以写|创建的方式打开目标文件
	dst, err := os.OpenFile(dstName, os.O_WRONLY|os.O_CREATE, 0644)
	if err != nil {
		fmt.Printf("open %s failed, err:%v.\n", dstName, err)
		return
	}
	defer dst.Close()
	return io.Copy(dst, src) //调用io.Copy()拷贝内容
}

func main() {
	// writeToFile()
	// writeToFileBufio()
	// writeToFileIoutil()

	dd, err := CopyFile("dist.txt", "write.txt")
	if err != nil {
		fmt.Println("copy file failed, err:", err)
		return
	}
	fmt.Println("copy done!", dd, err)
}
